package com.abel.web.controller;

import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.abel.domain.Application;
import com.abel.domain.AuthPrincipal;
import com.abel.domain.Education;
import com.abel.domain.Person;
import com.abel.domain.PersonProfile;
import com.abel.domain.PersonSearchCriteria;
import com.abel.domain.PersonalInformation;
import com.abel.domain.WorkExperience;
import com.abel.domain.types.PersonType;
import com.abel.manager.EducationManager;
import com.abel.manager.PersonProfileManager;
import com.abel.manager.WorkExperienceManager;
import com.abel.manager.exception.SearchException;
import com.abel.util.ApplicationFormGenerator;
import com.abel.util.DomainCreator;
import com.abel.util.UserSessionLocator;
import com.abel.web.view.DashboardViewBean;

public class SearchResultsController extends MultiActionController {

	protected final Log logger = LogFactory.getLog(getClass());
	
	private String searchView;

	private PersonProfileManager personProfileManager;
	
	private WorkExperienceManager workExperienceManager;
	
	private EducationManager educationManager;

	
	
	public ModelAndView submitToResumate(HttpServletRequest request,
			HttpServletResponse response) 
			throws Exception {

		logger.debug("@SearchResultsController : submitToResumate : entered");
		
		//handle form submission of Export to Resumate
		if (request.getParameter("exportToResumate") != null
				&& request.getParameter("exportToResumate").equals("Export to Resumate")) {
			
			//get the list of app ids
			//get person for each app id
			//write pdf to temp folder
			//zip the pdfs
			//stream the pdfs out
			return null;
		}
		else if (request.getParameter("search") != null
				&& request.getParameter("search").equals("Return to Search")) {

			return new ModelAndView("redirect:" + getSearchView());

		}
		else {
			return null;
		}
		
	}
	
	
	
	public ModelAndView printPDF(HttpServletRequest request,
			HttpServletResponse response) 
			throws Exception {
		
		logger.debug("@SearchResultsController : printPDF : entered");
		
		int userId = Integer.parseInt(request.getParameter("id"));
		int applicationId = Integer.parseInt(request.getParameter("appid"));
		PersonSearchCriteria criteria = new PersonSearchCriteria();
		criteria.setUserId(userId);
		criteria.setApplicationId(applicationId);
 
		Person person = null;
		OutputStream outputStream = null;
		
		try {
			//getting person information
			person = this.getPerson(criteria, PersonType.User);
		
			//sending the personal information to print pdf
			response.setHeader("Content-disposition","inline; filename=Application_Form_" + person.getApplication().getApplicationId()  + ".pdf");
			response.setContentType("application/pdf");
			outputStream = response.getOutputStream();
			
			ApplicationFormGenerator  formGenerator = new ApplicationFormGenerator();
			formGenerator.generateApplicationForm(response.getOutputStream(), person);
		}
		catch (Exception e) {

			logger.debug("@DashboardController : handleRequest : exception with getting personprofile and printing pdf" + e);
			e.printStackTrace();
			return new ModelAndView("error");
		}
		finally{

			outputStream.flush();
			outputStream.close();
			
		}
		
		return null;
	}

	
	
	public ModelAndView adminApplication(HttpServletRequest request,
			HttpServletResponse response) 
			throws Exception {

		logger.debug("@SearchResultsController : adminApplication : ");
		
		int userId = Integer.parseInt(request.getParameter("id"));
		int applicationId = Integer.parseInt(request.getParameter("appid"));
		PersonSearchCriteria criteria = new PersonSearchCriteria();
		criteria.setUserId(userId);
		criteria.setApplicationId(applicationId);
 
		Person person = null;
		try {
			//getting person information
			person = this.getPerson(criteria, PersonType.User);
		}
		catch (Throwable e) {
			
			logger.debug("@SearchResultController : handleRequest : exception with getting personprofile" + e);
			e.printStackTrace();
			return new ModelAndView("error");
			
		}
		
		//populate bean if existing application
		DashboardViewBean viewBean = new DashboardViewBean();
		PersonalInformation personalInformation = person.getApplication().getPersonProfile().getPersonalInformation();
		viewBean.setSsn(personalInformation.getSsn());
		if (personalInformation.getDateOfBirth() != null) {
			viewBean.setDateOfBirth(new SimpleDateFormat("MM/dd/yyyy").format(personalInformation.getDateOfBirth()));
		}
		viewBean.setFirstName(personalInformation.getFirstName());
		viewBean.setMi(personalInformation.getMiddleName());
		viewBean.setLastName(personalInformation.getLastName());
		viewBean.setAddress1(personalInformation.getAddressLine1());
		viewBean.setAddress2(personalInformation.getAddressLine2());
		viewBean.setCity(personalInformation.getCity());
		viewBean.setState(personalInformation.getState()); 
		viewBean.setZip(personalInformation.getZip());
		viewBean.setHomePhone(personalInformation.getHomePhone());
		viewBean.setAltPhone(personalInformation.getAlternatePhone());
		viewBean.setWorkPhone(personalInformation.getWorkPhone());
		//viewBean.setEmail(personalInformation.getEmail());  -- add email to class
		viewBean.setEmergencyContact(personalInformation.getEmergencyContact());
		viewBean.setEmergencyContactPhone(personalInformation.getEmergencyContactPhone());
		viewBean.setEmergencyContactRelation(personalInformation.getEmergencyContactRelation());
		
		//disabling links to other parts of the application if personal profile is not set
		Application application = person.getApplication();

		if (application.getApplicationId() > 0) {
			viewBean.setPersonalInfoAvailable(true);
		}
		
		viewBean.setUserRegularUser(true);

		Map<String, Object> modelMap = new HashMap<String, Object>();
		modelMap.put("dashboardView", viewBean);
		
		ModelAndView mav = new ModelAndView("adminapplication");
		mav.addAllObjects(modelMap);
		return mav;

	}


	/**
	 * @return the searchView
	 */
	public String getSearchView() {
		return searchView;
	}


	/**
	 * @param searchView the searchView to set
	 */
	public void setSearchView(String searchView) {
		this.searchView = searchView;
	}


	/**
	 * @param personProfileManager the personProfileManager to set
	 */
	public void setPersonProfileManager(PersonProfileManager personProfileManager) {
		this.personProfileManager = personProfileManager;
	}


	/**
	 * @param workExperienceManager the workExperienceManager to set
	 */
	public void setWorkExperienceManager(WorkExperienceManager workExperienceManager) {
		this.workExperienceManager = workExperienceManager;
	}


	/**
	 * @param educationManager the educationManager to set
	 */
	public void setEducationManager(EducationManager educationManager) {
		this.educationManager = educationManager;
	}
	

	private Person getPerson(PersonSearchCriteria criteria, PersonType personType) 
		throws SearchException {

		Person person = DomainCreator.createPerson(personType);
		 
		try {
			
			person.setUserId(criteria.getUserId());
			
			//setting the selected person as the current person in thread local so that it can be used by other components in the application
			UserSessionLocator.getUserSession().setPerson(person);
			
			PersonProfile personProfile = personProfileManager.getPersonProfile(criteria);
			person.getApplication().setPersonProfile(personProfile);
			person.getApplication().setApplicationId(criteria.getApplicationId());
			
			//getting work history to ensure that the threadlocal has all the attributes
			List<WorkExperience> workExperiences = this.workExperienceManager.getWorkExperience(criteria);
			person.getApplication().setWorkExperiences(workExperiences);
			
			//getting education to ensure that the threadlocal has all the attributes
			List<Education> education = this.educationManager.getEducationInformation(criteria);
			person.getApplication().setEducation(education);
			
			return person;
			
		}
		catch (Throwable e) {
			
			logger.debug("@DashboardController : handleRequest : exception with getting personprofile" + e);
			e.printStackTrace();
			throw new SearchException(e);
			
		}
		
	}
}
